package com.rfchina.okr.xianren.util;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import com.jfinal.kit.StrKit;

public class DateTimeUtil {

    public static final long SECOND = 1000L;

    public static final long MINUTE = 60 * SECOND;

    public static final long HOUR = 60 * MINUTE;

    public static final long DAY = 24 * HOUR;

    public static String DATE_FORMAT = "yyyy-MM-dd";

    public static String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    static public Date date(int y, int m, int d) {
        return date(y, m, d, 0, 0, 0);
    }

    static public Date date(int y, int m, int d, int h, int ms, int s) {
        Calendar cal = Calendar.getInstance();
        cal.set(y, m - 1, d, h, ms, s);
        return cal.getTime();
    }

    static public Date removeTime(Date d) {
        return setTime(d, 0, 0, 0);
    }

    static public Date setTime(Date d, int h, int m, int s) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        cal.set(Calendar.HOUR_OF_DAY, h);
        cal.set(Calendar.MINUTE, m);
        cal.set(Calendar.SECOND, s);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    static public String formatDate(String format, Date d) {
        return new SimpleDateFormat(format).format(d);
    }

    static public String formatDate(Date d) {
        return new SimpleDateFormat(DATE_FORMAT).format(d);
    }

    static public String formatDateTime(Date d) {
        return new SimpleDateFormat(DATETIME_FORMAT).format(d);
    }

    public static String formatPeriod(long period) {

        if (period == 0)
            return "0s";

        StringBuffer buf = new StringBuffer(20);

        long d;
        long r = period;

        d = r / DateTimeUtil.DAY;
        r = r % DateTimeUtil.DAY;
        if (d != 0) {
            buf.append(d).append("d");
        }

        d = r / DateTimeUtil.HOUR;
        r = r % DateTimeUtil.HOUR;
        if (d != 0) {
            buf.append(d).append("h");
        }

        d = r / DateTimeUtil.MINUTE;
        r = r % DateTimeUtil.MINUTE;
        if (d != 0) {
            buf.append(d).append("m");
        }

        d = r / DateTimeUtil.SECOND;
        r = r % DateTimeUtil.SECOND;
        if (d != 0 || r != 0) {
            buf.append(d);
            if (r != 0) {
                buf.append(".");
                if(r<10)buf.append("0");
                if(r<100)buf.append("0");
                buf.append(r);
            }
            buf.append("s");
        }

        return buf.toString();
    }

    public static Date setDate235959(Date date) {
        return setTime(date, 23, 59, 59);
    }

    static public Date parse(String v, String fm, Date def) {
        if (StrKit.isBlank(v))
            return def;
        try {
            return new SimpleDateFormat(fm).parse(v);
        } catch (Exception e) {
            return def;
        }
    }

    /**
     * yyyy-MM-dd
     */
    static public Date parseDate(String v, Date def) {
        return parse(v, "yyyy-MM-dd", def);
    }

    static public long parseDate(String v, long def) {
        Date r = parse(v, "yyyy-MM-dd", new Date(def));
        return r.getTime();
    }

    /**
     * yyyy-MM-dd HH:mm:ss
     */
    static public Date parseDateTime(String v, Date def) {
        return parse(v, "yyyy-MM-dd HH:mm:ss", def);
    }

    static public long parseDateTime(String v, long def) {
        Date r = parse(v, "yyyy-MM-dd HH:mm:ss", new Date(def));
        return r.getTime();
    }

    public static long parsePeriodValue(String value, long deflt) {
        if (StrKit.isBlank(value))
            return deflt;

        long sign = 1;
        long period = 0;

        int i = 0;
        int length = value.length();

        if (length > 0 && value.charAt(i) == '-') {
            sign = -1;
            i++;
        }

        while (i < length) {
            long delta = 0;
            char ch;

            for (; i < length && (ch = value.charAt(i)) >= '0' && ch <= '9'; i++) {
                delta = 10 * delta + ch - '0';
            }

            if (i >= length) {
                period += 1000 * delta;
            } else {
                switch (value.charAt(i++)) {
                case 's':
                case 'S':
                    period += SECOND * delta;
                    break;
                case 'M':
                case 'm':
                    period += MINUTE * delta;
                    break;
                case 'h':
                case 'H':
                    period += HOUR * delta;
                    break;
                case 'd':
                case 'D':
                    period += DAY * delta;
                    break;
                case 'w':
                case 'W':
                    period += 7L * DAY * delta;
                    break;
                default:
                    return deflt;
                }
            }
        }
        return sign * period;
    }

    
    public static Date getFirstDayOfWeek(Date date) {
        return getFirstDayOfWeek(date, Calendar.SUNDAY);
    }

     
    public static Date getFirstDayOfWeek(Date date, int firstDayOfWeek) {
        Calendar cal = Calendar.getInstance();
        if (date != null)
            cal.setTime(date);

        cal.setFirstDayOfWeek(firstDayOfWeek);
        cal.set(Calendar.DAY_OF_WEEK, firstDayOfWeek);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();

    }
 
    public static Date getLastDayOfWeek(Date date) {
        return getFirstDayOfWeek(date, Calendar.SUNDAY);
    }

    /**
     * �õ�ָ��������ص��ܵ����һ�� 00:00:00
     * 
     * @param date
     * @param firstDayOfWeek
     * @return
     */
    public static Date getLastDayOfWeek(Date date, int firstDayOfWeek) {
        Calendar cal = Calendar.getInstance();
        if (date != null)
            cal.setTime(date);
        cal.setFirstDayOfWeek(firstDayOfWeek);
        cal.set(Calendar.DAY_OF_WEEK, firstDayOfWeek);
        cal.add(Calendar.DAY_OF_WEEK, 6);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();

    }

    /**
     * �õ�ָ�����ڵ�������µĵ�һ��. 00:00:00
     * 
     * @param date
     * @return
     */
    public static Date getFirstDayOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        if (date != null)
            cal.setTime(date);

        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);

        return cal.getTime();
    }

    /**
     * �õ�ָ�����ڵ�����·ݵ����һ�� 00:00:00
     * 
     * @param date
     * @return
     */
    public static Date getLastDayOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        if (date != null)
            cal.setTime(date);

        cal.set(Calendar.DAY_OF_MONTH, cal
                .getActualMaximum(Calendar.DAY_OF_MONTH));
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);

        return cal.getTime();
    }

}